package org.opens.sql.genHandle.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import org.opens.freemarker.FreemarkerUtil;
import org.opens.sql.constant.GenProjectPath;
import org.opens.exception.BusinessException;
import org.opens.sql.genConfig.GenSqlConfig;
import org.opens.sql.genHandle.GenHandle;
import org.opens.util.DatabaseConnectInfoEntity;
import org.opens.util.FileUtil;

import java.io.File;
import java.util.*;

public class GenServiceHandle implements GenHandle {

    private static final String serviceFtlFilePath = "JavaService.ftl";

    private static final String serviceImplFtlFilePath = "JavaServiceImpl.ftl";

    @Override
    public void genCode(GenSqlConfig genSqlConfig) {
        if (StrUtil.isBlank(genSqlConfig.getGenEntityPublicConfig().getPackageInfo())) {
            throw new BusinessException("未配置实体包名, service终止生成!");
        }

        if (StrUtil.isBlank(genSqlConfig.getGenMapperPublicConfig().getDaoPackage())) {
            throw new BusinessException("未配置dao包名, service终止生成!");
        }

        if (StrUtil.isBlank(genSqlConfig.getGenServicePublicConfig().getPackageInfo())) {
            throw new BusinessException("未配置service包名, service终止生成!");
        }

        DatabaseConnectInfoEntity databaseConnectInfo = genSqlConfig.getDatabaseConnectInfo();

        String tableName = databaseConnectInfo.getTableName();

        // 首字母大写的驼峰命名格式的表名
        String ccTableName = StrUtil.upperFirst(StrUtil.toCamelCase(tableName));
        String serviceName = ccTableName + "Service";
        String serviceImplName = ccTableName + "ServiceImpl";
        String daoName = ccTableName + "Dao";
        String entityName = ccTableName + "Entity";

        String servicePackageInfo = genSqlConfig.getGenServicePublicConfig().getPackageInfo();
        String serviceImplPackageInfo = servicePackageInfo + ".impl";
        String daoPackageInfo = genSqlConfig.getGenMapperPublicConfig().getDaoPackage() + "." + daoName;
        String entityPackageInfo = genSqlConfig.getGenEntityPublicConfig().getPackageInfo() + "." + entityName;

        Set<String> serviceImportSet = new HashSet<>();
        serviceImportSet.add("com.baomidou.mybatisplus.extension.service.IService");
        serviceImportSet.add(entityPackageInfo);

        Set<String> serviceImplImportSet = new HashSet<>();
        serviceImplImportSet.add("org.springframework.stereotype.Service");
        serviceImplImportSet.add("com.baomidou.mybatisplus.extension.service.impl.ServiceImpl");
        serviceImplImportSet.add(daoPackageInfo);
        serviceImplImportSet.add(entityPackageInfo);

        if (genSqlConfig.getGenServicePublicConfig().isAutowiredDao()) {
            serviceImplImportSet.add("org.springframework.beans.factory.annotation.Autowired");
        }

        if (genSqlConfig.getGenServicePublicConfig().isWithSlf4jAnnotation()) {
            serviceImplImportSet.add("lombok.extern.slf4j.Slf4j");
        }

        Map<String, Object> genServicePublicConfig = BeanUtil.beanToMap(genSqlConfig.getGenServicePublicConfig());
        Map<String, Object> ftlMap = new HashMap<>();
        ftlMap.putAll(genServicePublicConfig);
        ftlMap.put("serviceName", serviceName);
        ftlMap.put("serviceImplName", serviceImplName);
        ftlMap.put("daoName", daoName);
        ftlMap.put("entityName", entityName);
        ftlMap.put("servicePackageInfo", servicePackageInfo);
        ftlMap.put("serviceImplPackageInfo", serviceImplPackageInfo);
        ftlMap.put("serviceImportSet", serviceImportSet);
        ftlMap.put("serviceImplImportSet", serviceImplImportSet);
        ftlMap.put("authorInfo", genSqlConfig.getAuthorInfo());
        ftlMap.put("genServicePublicConfig", genSqlConfig.getGenServicePublicConfig());

        genService(genSqlConfig, ftlMap);

        // service实现类需要引入service
        String servicePackageImportInfo = genSqlConfig.getGenServicePublicConfig().getPackageInfo() + "." + serviceName;
        serviceImplImportSet.add(servicePackageImportInfo);
        ftlMap.put("serviceImplImportSet", serviceImplImportSet);

        genServiceImpl(genSqlConfig, ftlMap);
    }

    private void genService(GenSqlConfig genSqlConfig, Map<String, Object> ftlMap) {
        // 将包的包含.的路径转换为真实路径
        String servicePath = StrUtil.replace(genSqlConfig.getGenServicePublicConfig().getPackageInfo(), ".", File.separator);
        // 父目录
        String descParentPath = FileUtil.pathSplicing(genSqlConfig.getGenPath(), GenProjectPath.MAVEN_PROJECT_PREFIX, servicePath);
        // java文件全路径
        String descPath = FileUtil.pathSplicing(descParentPath, StrUtil.upperFirst(StrUtil.toCamelCase(genSqlConfig.getDatabaseConnectInfo().getTableName())) + "Service.java");

        // 创建目录
        FileUtil.createFolder(descParentPath);

        FreemarkerUtil.compileProcess(descPath, ftlMap, serviceFtlFilePath);
    }

    private void genServiceImpl(GenSqlConfig genSqlConfig, Map<String, Object> ftlMap) {
        // 将包的包含.的路径转换为真实路径
        String servicePath = StrUtil.replace(genSqlConfig.getGenServicePublicConfig().getPackageInfo(), ".", File.separator);
        // 父目录
        String descParentPath = FileUtil.pathSplicing(genSqlConfig.getGenPath(), GenProjectPath.MAVEN_PROJECT_PREFIX, servicePath, "impl");
        // java文件全路径
        String descPath = FileUtil.pathSplicing(descParentPath, StrUtil.upperFirst(StrUtil.toCamelCase(genSqlConfig.getDatabaseConnectInfo().getTableName())) + "ServiceImpl.java");

        // 创建目录
        FileUtil.createFolder(descParentPath);

        FreemarkerUtil.compileProcess(descPath, ftlMap, serviceImplFtlFilePath);
    }

    @Override
    public void genCodeValid(GenSqlConfig genSqlConfig) {

    }

}
